//
//  NSDate+Utils.m
//  iOSCodeProject
//
//  Created by Fox on 14-7-18.
//  Copyright (c) 2014年 翔傲信息科技（上海）有限公司. All rights reserved.
//

#import "NSDate+Utils.h"

@implementation NSDate (Utils)


-(NSCalendarUnit) getAllNSCalendarUnit {
    ////http://my.oschina.net/yongbin45/blog/156181
    NSCalendarUnit calendarUnit = NSCalendarUnitEra |
            NSCalendarUnitYear |
            NSCalendarUnitMonth |
            NSCalendarUnitDay |
            NSCalendarUnitHour |
            NSCalendarUnitMinute |
            NSCalendarUnitSecond |
            NSCalendarUnitWeekday |
            NSCalendarUnitWeekdayOrdinal |
            NSCalendarUnitQuarter |
            NSCalendarUnitWeekOfMonth |
            NSCalendarUnitWeekOfYear |
            NSCalendarUnitYearForWeekOfYear |
            NSCalendarUnitNanosecond |
            NSCalendarUnitCalendar |
            NSCalendarUnitTimeZone;
    return calendarUnit;
}

#pragma mark - Date Property

- (NSInteger)year {

    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSYearCalendarUnit fromDate:self];
    return [components year];

}

- (NSInteger)era {

    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSCalendarUnitEra fromDate:self];
    return [components era];

}

- (NSInteger)month {

    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSMonthCalendarUnit fromDate:self];
    return [components month];

}


- (NSInteger)dayOfMonth {

    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSDayCalendarUnit fromDate:self];
    return [components day];

}

- (NSInteger)countdaysInYear {
    return [self isLeapYear] ? 366 : 365;
}


- (NSInteger)dayInYear {
    NSInteger days = 0;
    NSInteger month = self.month;

    switch (month) {
        case 1:
            days = 0;
            break;
        case 2:
            days = 31;
            break;
        case 3:
            days = 31 + 28;
            break;
        case 4:
            days = 31 + 28 + 31;
            break;
        case 5:
            days = 31 + 28 + 31 + 30;
            break;
        case 6:
            days = 31 + 28 + 31 + 30 + 31;
            break;
        case 7:
            days = 31 + 28 + 31 + 30 + 31 + 30;
            break;
        case 8:
            days = 31 + 28 + 31 + 30 + 31 + 30 + 31;
            break;
        case 9:
            days = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
            break;
        case 10:
            days = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
            break;
        case 11:
            days = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
            break;
        case 12:
            days = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
            break;
    };
    if ([self isLeapYear]) {
        days = days + 1;
    }
    return days;
}


- (NSInteger)numDaysInMonth {

    NSCalendar *cal = [NSCalendar currentCalendar];
    NSRange rng = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self];
    NSUInteger numberOfDaysInMonth = rng.length;
    return numberOfDaysInMonth;
}

- (NSInteger)countDaysInMonth:(NSInteger)month {
    if (month == 1 ||
            month == 3 ||
            month == 5 ||
            month == 7 ||
            month == 8 ||
            month == 10) {
        return 31;
    }
    if (month == 2) {
        if ([self isLeapYear]) {
            return 29;
        }
        return 28;
    }
    return 30;
}


- (NSInteger)countDaysInMonth {
    if (self.month == 1 ||
            self.month == 3 ||
            self.month == 5 ||
            self.month == 7 ||
            self.month == 8 ||
            self.month == 10 ||
            self.month == 11) {
        return 31;
    }
    if (self.month == 2) {
        if ([self isLeapYear]) {
            return 29;
        }
        return 28;
    }
    return 30;
}

- (NSInteger)countWeeksInYear {
    //获取一年的最后一天
    NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSString *str=[NSString stringWithFormat:@"%d-%02d-%02d", self.year, 12, 31];
    NSDate *maxDate = [formatter dateFromString:str];

    //获取最后一天是多少周
    //w: 1~53 (0 padded Week of Year, 1st day of week = Sunday, NB: 1st week of year starts from the last Sunday of last year) 一年的第几周, 一周的开始为周日,第一周从去年的最后一个周日起算
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"w"];
    NSString *maxWeekInThisYear = [dateFormatter stringFromDate:maxDate];


    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:maxDate];
    maxWeekInThisYear = [NSString stringWithFormat:@"%i",components.weekOfYear];

    return 52;//最后一个周计算不准
}


- (NSInteger)weekOfYear {
    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:self];
    return [components weekOfYear];
}

- (NSInteger)weekOfMonth {
    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:self];
    return [components weekOfMonth];
}

- (NSInteger)weekdayOrdinal {
    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:self];
    return [components weekdayOrdinal];
}


- (NSInteger)weekday {
    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:self];
    return [components weekday];
}

- (NSInteger)yearForWeekOfYear {
    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:self];
    return [components yearForWeekOfYear];
}

- (BOOL)isLeapYear {
    NSInteger year = self.year;
    if ((year / 4 == 0 && year / 100 != 0) || (year / 400 == 0)) {
        return YES;
    } else {
        return NO;
    }
}

- (BOOL)isLeapMonth {
    NSCalendar *gregorian = [[NSCalendar alloc]
            initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //http://my.oschina.net/yongbin45/blog/156181
    NSDateComponents *components = [gregorian components:[self getAllNSCalendarUnit]
                                                fromDate:self];
    return [components isLeapMonth];
}


#pragma mark - Format Date

+ (NSString *)currentTimeString {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];

    return [dateFormatter stringFromDate:[NSDate date]];
}

+ (NSString *)currentFullTimeString {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

    return [dateFormatter stringFromDate:[NSDate date]];
}

+ (NSString *)currentDetailTimeString {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"HH:mm:ss"];

    return [dateFormatter stringFromDate:[NSDate date]];
}

+ (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)dateFormatterString {
    if (!dateString) return nil;

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:dateFormatterString];

    NSDate *theDate = [formatter dateFromString:dateString];

    return theDate;
}

+ (NSDate *)dateWithDateString:(NSString *)str {
    return [[self class] dateWithString:str formatString:@"yyyy-MM"];
}

+ (NSDate *)dateWithDateTimeString:(NSString *)str {
    return [[self class] dateWithString:str formatString:@"yyyy-MM-dd HH:mm:ss"];
}

- (NSString *)formatStringWithFormat:(NSString *)formatString {

    if (formatString.length == 0) {
        return @"";
    }
    //@"yyyy-MM-dd"
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:formatString];

    return [dateFormatter stringFromDate:self];
}

+ (NSString *)dateFormTimestampString:(NSString *)timestamp {

    NSTimeInterval timeInterval = [timestamp doubleValue];
    NSDate *confromTimsp = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"yyyy-MM-dd HH:MM:ss"];

    return [formatter stringFromDate:confromTimsp];
}

+ (NSString *)dateFormTimestampString:(NSString *)timestamp format:(NSString *)format {
    NSTimeInterval timeInterval = [timestamp doubleValue];
    NSDate *confromTimsp = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:format];

    return [formatter stringFromDate:confromTimsp];
}

+ (NSString *)dateFormMoreTimestampString:(NSString *)timestamp format:(NSString *)format {
    NSTimeInterval timeInterval = [timestamp doubleValue];
    NSDate *confromTimsp = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [dateFormatter setDateFormat:format];
    if (format == nil)
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];

    NSString *dateString = [dateFormatter stringFromDate:confromTimsp];
    return dateString;
}


+ (NSString *)dateFormmterFormSecond:(int)count {

    //先计算天数
    int laveCounts = count;
    int days = laveCounts / (60 * 60 * 12);
    laveCounts = laveCounts - days * (60 * 60 * 12);

    //计算小时
    int hours = laveCounts / (60 * 60);
    laveCounts = laveCounts - hours * (60 * 60);

    //计算分钟
    int minutes = laveCounts / 60;
    laveCounts = laveCounts - minutes * 60;

    //剩余未秒数
    int second = laveCounts;

    return [NSString stringWithFormat:@"%d天%d小时%d分%d秒", days, hours, minutes, second];
}

+ (NSString *)dateFormmterFormSecond2:(int)count{

    //先计算天数
    int laveCounts = count;
    int days = laveCounts/(60*60*12);
    laveCounts = laveCounts - days*(60*60*12);

    //计算小时
    int hours = laveCounts/(60*60);
    laveCounts = laveCounts - hours*(60*60);

    //计算分钟
    int minutes = laveCounts/60;
    laveCounts = laveCounts - minutes*60;

    //剩余未秒数
    int second = laveCounts;


    if (days != 0) {
        return [NSString stringWithFormat:@"%d天",days];
    }
     else  {
        return [NSString stringWithFormat:@"%2d:%2d:%2d",hours,minutes,second];
    }
    //return [NSString stringWithFormat:@"%d天%d小时%d分%d秒",days,hours,minutes,second];
}


- (NSString *)formattedExactRelativeDate {

    NSTimeInterval time = [self timeIntervalSince1970];
    NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval diff = now - time;

    if (diff < 10) {
        return [NSString stringWithFormat:@"刚刚"];
    } else if (diff < 60) {
        return [NSString stringWithFormat:@"%d秒前", (int) diff];
    }

    diff = round(diff / 60);
    if (diff < 60) {
        if (diff == 1) {
            return [NSString stringWithFormat:@"%d分钟前", (int) diff];
        } else {
            return [NSString stringWithFormat:@"%d分钟前", (int) diff];
        }
    }

    diff = round(diff / 60);
    if (diff < 24) {
        if (diff == 1) {
            return [NSString stringWithFormat:@"%d小时前", (int) diff];
        } else {
            return [NSString stringWithFormat:@"%d小时前", (int) diff];
        }
    }

    if (diff < 7) {
        if (diff == 1) {
            return @"昨天";
        } else {
            return [NSString stringWithFormat:@"%d天前", (int) diff];
        }
    }

    return [self formattedDateWithFormatString:@"MM/dd/yy"];
}

- (NSString *)formattedDateWithFormatString:(NSString *)dateFormatterString {
    if (!dateFormatterString) return nil;

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:dateFormatterString];
    [formatter setAMSymbol:@"am"];
    [formatter setPMSymbol:@"pm"];
    return [formatter stringFromDate:self];
}

+ (NSString *)pastDateString:(int)pageDays {

    NSDate *lastDate = [[NSDate date] dateByAddingTimeInterval:pageDays * 86400 * -1];
    NSMutableString *currentString = [NSMutableString stringWithFormat:@"%@", lastDate];
    return [currentString substringToIndex:10];
}

+ (NSString *)addDateString:(int)pageDays {

    NSDate *lastDate = [[NSDate date] dateByAddingTimeInterval:pageDays * 86400];
    NSMutableString *currentString = [NSMutableString stringWithFormat:@"%@", lastDate];
    return [currentString substringToIndex:10];
}

+ (NSString *)pastMonthDateString:(int)pastMonth {

    NSDateComponents *comps = [[NSDateComponents alloc] init];
    [comps setMonth:-1 * pastMonth];
    NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDate *mDate = [calender dateByAddingComponents:comps toDate:[NSDate date] options:0];
    NSMutableString *currentString = [NSMutableString stringWithFormat:@"%@", mDate];
    return [currentString substringToIndex:10];
}

#pragma mark - Time comparison

- (BOOL)isPastDate {
    NSDate *now = [NSDate date];
    if ([[now earlierDate:self] isEqualToDate:self]) {
        return YES;
    } else {
        return NO;
    }
}

- (BOOL)isDateToday {
    return [[[NSDate date] midnightDate] isEqual:[self midnightDate]];
}

- (BOOL)isDateYesterday {
    return [[[NSDate dateWithTimeIntervalSinceNow:-86400] midnightDate]
            isEqual:[self midnightDate]];
}

- (NSDate *)midnightDate {
    return [[NSCalendar currentCalendar] dateFromComponents:
            [[NSCalendar currentCalendar]                                        components:
                    (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:self]];
}

//后加
+ (NSString *)ymmdateFormTimestampString:(NSString *)timestamp {

    NSTimeInterval timeInterval = [timestamp doubleValue];
    NSDate *confromTimsp = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"yyyy-MM-dd"];

    return [formatter stringFromDate:confromTimsp];
}

//后加
+ (NSString *)dateFormTimestampString:(NSString *)timestamp withFormat:(NSString *)stringFormat {

    NSTimeInterval timeInterval = [timestamp doubleValue];
    NSDate *confromTimsp = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:stringFormat];

    return [formatter stringFromDate:confromTimsp];
}

//后加
+ (NSString *)homeNewsdateFormTimestampString:(NSString *)timestamp {

    NSTimeInterval timeInterval = [timestamp doubleValue];
    NSDate *confromTimsp = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"yyyy.MM.dd"];
    return [formatter stringFromDate:confromTimsp];
}

@end
